using System.Collections;
using Reflector.CodeModel;

namespace LanguageWriterHelper
{
    public class MetadataVisitor : VisitorBase
    {
        IDictionary currentTypes = new Hashtable();
        bool expandDeclaredTypes = false;

        public void Visit(IArrayType value)
        {
            if (value == null)
                return;
            
            WriteStartElement("IArrayType");

            WriteStartElement("Dimensions");
            Visit(value.Dimensions);
            WriteEndElement();

            WriteStartElement("ElementType");
            Visit(value.ElementType);
            WriteEndElement();
            
            WriteEndElement();
        }
        
        public void Visit(IArrayDimension value)
        {
            if (value == null)
                return;

            WriteStartElement("IArrayDimension");
                        
            WriteElement("LowerBound", value.LowerBound.ToString());
            WriteElement("UpperBound", value.UpperBound.ToString());
            
            WriteEndElement();
        }

        public void Visit(IArrayDimensionCollection value)
        {
            if (value == null || value.Count == 0)
                return;

            WriteStartElement("IArrayDimensionCollection");
            
            foreach (IArrayDimension ad in value)
            {
                Visit(ad);
            }

            WriteEndElement();
        }
        
        public void Visit(IAssembly value)
        {
            if (value == null)
                return;

            WriteStartElement("IAssembly");
                        
            WriteElement("AssemblyType", value.Type.ToString());
            WriteElement("HashAlgorithm", value.HashAlgorithm.ToString());

            if ((Manager.Configuration["ShowCustomAttributes"] == "true") && (value.Attributes.Count != 0))
            {
                Manager.ReflectorVisitor.Visit((ICustomAttributeProvider)value);
            }
            Manager.ReflectorVisitor.Visit((IAssemblyLocation)value);

            if (!Manager.VisibilityConfiguration["only-assembly"])
            {
                WriteStartElement("EntryPoint");
                Visit(value.EntryPoint);
                WriteEndElement();

                WriteStartElement("Modules");
                Visit(value.Modules);
                WriteEndElement();

                WriteStartElement("Resources");
                Visit(value.Resources);
                WriteEndElement();
            }
            WriteEndElement();
        }

        public void Visit(IAssemblyCollection value)
        {
            if (value == null || value.Count == 0)
                return;

            WriteStartElement("IAssemblyCollection");
            
            foreach (IAssembly assm in value)
            {
                Visit(assm);
            }

            WriteEndElement();
        }

        public void Visit(IAssemblyReference value)
        {
            if (value == null)
                return;

            WriteStartElement("IAssemblyReference");          

            WriteElement("IAssemblyLocation", value.ToString());
            WriteElement("Culture", value.Culture);
            WriteElement("HashValue", GetByteArrayText(value.HashValue));
            WriteElement("Name", value.Name);
            WriteElement("PublicKey", GetByteArrayText(value.PublicKey));
            WriteElement("PublicKeyToken", GetByteArrayText(value.PublicKeyToken));
            WriteElement("Retargetable", value.Retargetable.ToString());
            WriteElement("Version", value.Version.ToString());

            WriteEndElement();
        }

        public void Visit(IAssemblyReferenceCollection value)
        {
            if (value == null || value.Count == 0)
                return;

            WriteStartElement("IAssemblyReferenceCollection");
            
            foreach (IAssemblyReference assmRef in value)
            {
                Visit(assmRef);
            }

            WriteEndElement();
        }

        public void Visit(ICustomAttribute value)
        {
            if (value == null)
                return;

            WriteStartElement("ICustomAttribute");

            WriteStartElement("Arguments");
            Manager.ExpressionVisitor.Visit(value.Arguments);
            WriteEndElement();

            WriteStartElement("Constructor");
            Visit(value.Constructor);
            WriteEndElement();

            WriteEndElement();
        }

        public void Visit(ICustomAttributeCollection value)
        {
            if (value == null || value.Count == 0 )
                return;
                        
            WriteStartElement("ICustomAttributeCollection");
            
            foreach (ICustomAttribute att in value)
            {
                Visit(att);
            }

            WriteEndElement();
        }

        public void Visit(IEmbeddedResource value)
        {
            if (value == null)
                return;

            WriteStartElement("IEmbeddedResource");

            WriteStartElement("Module");
            Visit(value.Module);
            WriteEndElement();

            WriteElement("Name", value.Name);
            WriteElement("ByteCount", value.Value.Length.ToString());
            WriteElement("Visibility", value.Visibility.ToString());
            
            WriteEndElement();
        }

        public void Visit(IEventDeclaration value)
        {
            if (value == null)
                return;

            WriteStartElement("IEventDeclaration");
            // Not necessary since IEventReference is also IMemberReference         
            //Visit((IMemberReference)value);
            Visit((IEventReference)value);
            if (Manager.Configuration["ShowMethodDeclarationBody"] == "true")
            {
                WriteElement("RuntimeSpecialName", value.RuntimeSpecialName.ToString());
                WriteElement("SpecialName", value.SpecialName.ToString());          

                WriteStartElement("AddMethod");
                Visit(value.AddMethod);
                WriteEndElement();

                WriteStartElement("InvokeMethod");
                Visit(value.InvokeMethod);
                WriteEndElement();

                WriteStartElement("RemoveMethod");
                Visit(value.RemoveMethod);
                WriteEndElement();
            }
            WriteEndElement();
        }

        public void Visit(IEventDeclarationCollection value)
        {
            if (value == null || value.Count == 0)
                return;

            WriteStartElement("IEventDeclarationCollection");
            
            foreach (IEventDeclaration eventDef in value)
            {
                Visit(eventDef);
            }

            WriteEndElement();
        }

        public void Visit(IEventReference value)
        {
            if (value == null)
                return;

            WriteStartElement("IEventReference");
                        
            Visit((IMemberReference)value);

            WriteStartElement("EventType");
            Visit(value.EventType);
            WriteEndElement();

            WriteStartElement("GenericEvent");
            Visit(value.GenericEvent);
            WriteEndElement();

            WriteEndElement();
        }
        public void Visit(IFieldDeclaration value)
        {
            if (value == null)
                return;

            WriteStartElement("IFieldDeclaration");

            // Not necessary since IMemberDeclaration is also IMemberReference         
            //Visit((IMemberDeclaration)value);
            Visit((IFieldReference)value);

            if (Manager.Configuration["ShowMethodDeclarationBody"] == "true")
            {
                WriteElement("Literal", value.Literal.ToString());
                WriteElement("ReadOnly", value.ReadOnly.ToString());
                WriteElement("RuntimeSpecialName", value.RuntimeSpecialName.ToString());
                WriteElement("SpecialName", value.SpecialName.ToString());
                WriteElement("Static", value.Static.ToString());
                WriteElement("Visibility", value.Visibility.ToString());

                WriteStartElement("Initializer");
                Manager.ExpressionVisitor.Visit(value.Initializer);
                WriteEndElement();
            }
            WriteEndElement();
        }

        public void Visit(IFieldDeclarationCollection value)
        {
            if (value == null || value.Count == 0)
                return;

            WriteStartElement("IFieldDeclarationCollection");
            
            foreach (IFieldDeclaration fieldDef in value)
            {
                Visit(fieldDef);
            }

            WriteEndElement();
        }


        public void Visit(IFieldReference value)
        {
            if (value == null)
                return;

            WriteStartElement("IFieldReference");
            
            Visit((IMemberReference)value);
            
            WriteStartElement("FieldType");
            Visit(value.FieldType);
            WriteEndElement();

            WriteStartElement("GenericField");
            Visit(value.GenericField);
            WriteEndElement();

            WriteEndElement();
        }


        public void Visit(IFileResource value)
        {
            if (value == null)
                return;

            WriteStartElement("IFieldReference");

            WriteElement("HashValue", GetByteArrayText(value.HashValue));
            WriteElement("Location", value.Location);
            WriteElement("Name", value.Name);
            WriteElement("Offset", value.Offset.ToString());
            WriteElement("Visibility", value.Visibility.ToString());

            WriteStartElement("Module");
            Visit(value.Module);
            WriteEndElement();

            WriteEndElement();
        }

        public void Visit(IGenericArgument value)
        {
            if (value == null)
                return;

            WriteStartElement("IGenericArgument");

            WriteElement("Position", value.Position.ToString());
            WriteStartElement("Owner");
            
            Manager.ReflectorVisitor.Visit(value.Owner);
            WriteEndElement();

            WriteEndElement();
        }

        public void Visit(IGenericParameter value)
        {
            if (value == null)
                return;

            WriteStartElement("IGenericParameter");

            WriteElement("Name", value.Name);
            WriteElement("Position", value.Position.ToString());
            WriteElement("Variance", value.Variance.ToString());

            WriteStartElement("Attributes");
            Visit(value.Attributes);
            WriteEndElement();

            WriteStartElement("Constraints");
            Visit(value.Constraints);
            WriteEndElement();

            WriteStartElement("Owner");
            Manager.ReflectorVisitor.Visit(value.Owner);
            WriteEndElement();           

            WriteEndElement();
        }
        public void Visit(IMemberDeclaration value)
        {
            if (value == null)
                return;

            WriteStartElement("IMemberDeclaration");

            if ((Manager.Configuration["ShowCustomAttributes"] == "true") && (value.Attributes.Count != 0))
            {
                Manager.ReflectorVisitor.Visit((ICustomAttributeProvider)value);
            }
            Visit((IMemberReference)value);

            WriteEndElement();
        }
        
        public void Visit(IMemberReference value)
        {
            if (value == null)
                return;

            WriteStartElement("IMemberReference");
            
            WriteElement("Name", value.Name);

            WriteStartElement("DeclaringType");
            if (expandDeclaredTypes)
            {
                Visit(value.DeclaringType);
            }
            else
            {
                ITypeReference typeRef = value.DeclaringType as ITypeReference;
                if (typeRef != null)
                {
                    WriteElement("Name", typeRef.Name);
                    WriteElement("Namespace", typeRef.Namespace);
                    WriteElement("ValueType", typeRef.ValueType.ToString());
                }
            }
            WriteEndElement();

            WriteEndElement();
        }
        
        public void Visit(IMethodDeclaration value)
        {
            if (value == null)
                return;

            WriteStartElement("IMethodDeclaration");

            // Not necessary since IMethodReference is also IMemberReference, which is a IMemberDeclaration
            //Visit((IMemberDeclaration)value);
            Visit((IMethodReference)value);
            if (Manager.Configuration["ShowMethodDeclarationBody"] == "true")
            {
                WriteElement("Abstract", value.Abstract.ToString());
                WriteElement("Final", value.Final.ToString());
                WriteElement("HideBySignature", value.HideBySignature.ToString());
                WriteElement("NewSlot", value.NewSlot.ToString());
                WriteElement("RuntimeSpecialName", value.RuntimeSpecialName.ToString());
                WriteElement("SpecialName", value.SpecialName.ToString());
                WriteElement("Static", value.Static.ToString());
                WriteElement("Virtual", value.Virtual.ToString());
                WriteElement("Visibility", value.Visibility.ToString());

                WriteStartElement("Overrides");
                Visit(value.Overrides);
                WriteEndElement();
                 
                WriteStartElement("Body");
                Manager.StatementVisitor.Visit(value.Body as IBlockStatement);
                WriteEndElement();                    
            }
                        
            WriteEndElement();
        }

        public void Visit(IMethodDeclarationCollection value)
        {
            if (value == null || value.Count == 0)
                return;

            WriteStartElement("IMethodDeclarationCollection");
            
            foreach (IMethodDeclaration methodDef in value)
            {
                Visit(methodDef);
            }

            WriteEndElement();
        }
        
        public void Visit(IMethodReference value)
        {
            if (value == null)
                return;

            WriteStartElement("IMethodReference");
            
            Visit((IMemberReference)value);
            Visit((IMethodSignature)value);
            Manager.ReflectorVisitor.Visit((IGenericArgumentProvider)value);

            if (value.GenericMethod != null)
            {
                WriteStartElement("GenericMethod");
                Visit(value.GenericMethod);
                WriteEndElement();
            }

            WriteEndElement();
        }

        public void Visit(IMethodReferenceCollection value)
        {
            if (value == null || value.Count == 0)
                return;

            WriteStartElement("IMethodReferenceCollection");
            
            foreach (IMethodReference methodRef in value)
            {
                Visit(methodRef);
            }

            WriteEndElement();
        }

        public void Visit(IMethodReturnType value)
        {
            if (value == null)
                return;

            WriteStartElement("IMethodReturnType");
                        
            Manager.ReflectorVisitor.Visit((ICustomAttributeProvider)value);

            WriteStartElement("Type");
            Visit(value.Type);
            WriteEndElement();

            WriteEndElement();
        }

        public void Visit(IMethodSignature value)
        {
            if (value == null)
                return;

            WriteStartElement("IMethodSignature");
            
            WriteElement("CallingConvention", value.CallingConvention.ToString());
            WriteElement("ExplicitThis", value.ExplicitThis.ToString());
            WriteElement("HasThis", value.HasThis.ToString());

            WriteStartElement("Parameters");
            Visit(value.Parameters);
            WriteEndElement();

            WriteStartElement("ReturnType");
            Visit(value.ReturnType);
            WriteEndElement();

            WriteEndElement();
        }

        public void Visit(IModule value)
        {
            if (value == null)
                return;

            WriteStartElement("IModule");           
                        
            Manager.ReflectorVisitor.Visit((ICustomAttributeProvider)value);
            Visit((IModuleReference)value);
            WriteElement("FileAlignment", "0x" + value.FileAlignment.ToString("x"));
            WriteElement("Location", value.Location);
            WriteElement("TargetRuntimeVersion", value.TargetRuntimeVersion);
            WriteElement("Version", value.Version.ToString());

            if (!Manager.VisibilityConfiguration["only-module"])
            {
                WriteStartElement("AssemblyReferences");
                Visit(value.AssemblyReferences);
                WriteEndElement();

                WriteStartElement("ModuleReferences");
                Visit(value.ModuleReferences);
                WriteEndElement();

                WriteStartElement("Types");
                Visit(value.Types);
                WriteEndElement();

                WriteStartElement("UnmanagedResources");
                Visit(value.UnmanagedResources);
                WriteEndElement();
            }
            WriteEndElement();
        }

        public void Visit(IModuleCollection value)
        {
            if (value == null || value.Count == 0)
                return;

            WriteStartElement("IModuleCollection");
            
            foreach (IModule mod in value)
            {
                Visit(mod);
            }

            WriteEndElement();
        }

        public void Visit(IModuleReference value)
        {
            if (value == null)
                return;

            WriteStartElement("IModuleReference");          

            WriteElement("Name", value.Name);

            WriteEndElement();
        }

        public void Visit(IModuleReferenceCollection value)
        {
            if (value == null || value.Count == 0)
                return;

            WriteStartElement("IModuleReferenceCollection");

            foreach (IModuleReference modRef in value)
            {
                Visit(modRef);
            }

            WriteEndElement();
        }

        public void Visit(INamespace value)
        {
            if (value == null)
                return;

            WriteStartElement("INamespace");            

            WriteElement("Name", value.Name);

            if (Manager.Configuration["ShowNamespaceBody"] == "true")
            {
                WriteStartElement("Types");
                Visit(value.Types);
                WriteEndElement();
            }

            WriteEndElement();
        }

        public void Visit(IOptionalModifier value)
        {
            if (value == null)
                return;

            WriteStartElement("IOptionalModifier");

            WriteStartElement("ElementType");
            Visit(value.ElementType);
            WriteEndElement();

            WriteStartElement("Modifier");
            Visit(value.Modifier);
            WriteEndElement();

            WriteEndElement();
        }

        public void Visit(IParameterDeclaration value)
        {
            if (value == null)
                return;

            WriteStartElement("IParameterDeclaration");
            
            Manager.ReflectorVisitor.Visit((ICustomAttributeProvider)value);
            Visit((IParameterReference)value);

            WriteStartElement("ParameterType");
            Visit(value.ParameterType);
            WriteEndElement();

            WriteEndElement();
        }

        public void Visit(IParameterDeclarationCollection value)
        {
            if (value == null || value.Count == 0)
                return;

            WriteStartElement("IParameterDeclarationCollection");
            
            foreach (IParameterDeclaration paramRef in value)
            {
                Visit(paramRef);
            }
            
            WriteEndElement();
        }

        public void Visit(IParameterReference value)
        {
            if (value == null)
                return;

            WriteStartElement("IParameterReference");        
                        
            WriteElement("Name", value.Name);

            WriteEndElement();
        }
       
        public void Visit(IPointerType value)
        {
            if (value == null)
                return;

            WriteStartElement("IPointerType");

            WriteStartElement("ElementType");
            Visit(value.ElementType);
            WriteEndElement();

            WriteEndElement();
        }       
       
        public void Visit(IPropertyDeclaration value)
        {
            if (value == null)
                return;

            WriteStartElement("IPropertyDeclaration");

            // Not necessary since IEventReference is also IMemberReference, which is a IMemberDeclaration
            //Visit((IMemberDeclaration)value);
            Visit((IPropertyReference)value);
            if (Manager.Configuration["ShowMethodDeclarationBody"] == "true")
            {
                WriteElement("HasThis", value.HasThis.ToString());
                WriteElement("RuntimeSpecialName", value.RuntimeSpecialName.ToString());
                WriteElement("SpecialName", value.SpecialName.ToString());

                WriteStartElement("GetMethod");
                Visit(value.GetMethod);
                WriteEndElement();

                WriteStartElement("Initializer");
                Manager.ExpressionVisitor.Visit(value.Initializer);
                WriteEndElement();

                WriteStartElement("SetMethod");
                Visit(value.SetMethod);
                WriteEndElement();
            }
            WriteEndElement();
        }

        public void Visit(IPropertyDeclarationCollection value)
        {
            if (value == null || value.Count == 0)
                return;

            WriteStartElement("IPropertyDeclarationCollection");

            foreach (IPropertyDeclaration propertyDecl in value)
            {
                Visit(propertyDecl);
            }

            WriteEndElement();
        }
        
        public void Visit(IPropertyReference value)
        {
            if (value == null)
                return;

            WriteStartElement("IPropertyReference");

            Visit((IMemberReference)value);

            WriteStartElement("GenericProperty");
            Visit(value.GenericProperty);
            WriteEndElement();

            WriteStartElement("Parameters");
            Visit(value.Parameters);
            WriteEndElement();

            WriteStartElement("PropertyType");
            Visit(value.PropertyType);
            WriteEndElement();

            WriteEndElement();
        }

        public void Visit(IReferenceType value)
        {
            if (value == null)
                return;

            WriteStartElement("IReferenceType");

            WriteStartElement("ElementType");
            Visit(value.ElementType);
            WriteEndElement();

            WriteEndElement();
        }

        public void Visit(IReferenceTypeConstraint value)
        {
            if (value == null)
                return;

            WriteEmptyElement("IReferenceTypeConstraint");
        }

        public void Visit(IRequiredModifier value)
        {
            if (value == null)
                return;

            WriteStartElement("IRequiredModifier");

            WriteStartElement("ElementType");
            Visit(value.ElementType);
            WriteEndElement();

            WriteStartElement("Modifier");
            Visit(value.Modifier);
            WriteEndElement();

            WriteEndElement();
        }
        
        public void Visit(IResource value)
        {
            if (value == null)
                return;

            WriteStartElement("IResource");

            WriteElement("Name", value.Name);
            WriteElement("Visibility", value.Visibility.ToString());

            if (!Manager.VisibilityConfiguration["only-resource"])
            {
                WriteStartElement("Module");
                Visit(value.Module);
                WriteEndElement();
            }
            WriteEndElement();
        }
        public void Visit(IResourceCollection value)
        {
            if (value == null || value.Count == 0)
                return;

            WriteStartElement("IResourceCollection");

            foreach (IResource res in value)
            {
                Visit(res);
            }

            WriteEndElement();
        }

        public void Visit(IType value)
        {
            if (value == null)
                return;

            if (!currentTypes.Contains(value))
            {
                currentTypes.Add(value, value);

                Visit(value as IArrayType);
                Visit(value as IDefaultConstructorConstraint);
                Visit(value as IMethodSignature);
                Visit(value as IGenericArgument);
                Visit(value as IGenericParameter);
                Visit(value as IOptionalModifier);
                Visit(value as IPointerType);
                Visit(value as IReferenceType);
                Visit(value as IReferenceTypeConstraint);
                Visit(value as IRequiredModifier);
                Visit(value as ITypeReference);
                Visit(value as IValueTypeConstraint);
                
                currentTypes.Remove(value);
            }
            else
            {
                ITypeReference typeRef = value as ITypeReference;
                if (typeRef != null)
                {
                    WriteElement("Name", typeRef.Name);
                    WriteElement("Namespace", typeRef.Namespace);
                    WriteElement("ValueType", typeRef.ValueType.ToString());
                }

                IGenericParameter genParam = value as IGenericParameter;
                {
                    WriteElement("Name", genParam.Name);
                    WriteElement("Variance", genParam.Variance.ToString());
                }
            }
        }
        
        public void Visit(IDefaultConstructorConstraint value)
        {
            if (value == null)
                return;

            WriteEmptyElement("IDefaultConstructorConstraint");
        }

        public void Visit(ITypeCollection value)
        {
            if (value == null || value.Count == 0)
                return;

            WriteStartElement("ITypeCollection");

            foreach (IType typ in value)
            {
                Visit(typ);
            }

            WriteEndElement();
        }

        public void Visit(ITypeDeclaration value)
        {
            if (value == null)
                return;

            WriteStartElement("ITypeDeclaration");
            
            Manager.ReflectorVisitor.Visit((ICustomAttributeProvider)value);
            Visit((ITypeReference)value);
                        
            WriteElement("Abstract", value.Abstract.ToString());
            WriteElement("BeforeFieldInit", value.BeforeFieldInit.ToString());
            WriteElement("Interface", value.Interface.ToString());
            WriteElement("RuntimeSpecialName", value.RuntimeSpecialName.ToString());
            WriteElement("Sealed", value.Sealed.ToString());
            WriteElement("SpecialName", value.SpecialName.ToString());
            WriteElement("Visibility", value.Visibility.ToString());

            if (value.GenericArguments != null && value.GenericArguments.Count > 0)
            {
                WriteStartElement("GenericArguments");
                Visit(value.GenericArguments);
                WriteEndElement();
            }

            if (value.GenericType != null)
            {
                WriteStartElement("GenericType");
                Visit(value.GenericType);
                WriteEndElement();
            }
                        
            //if (!Manager.VisibilityConfiguration["only-typedecl"])
            if (Manager.Configuration["ShowTypeDeclarationBody"] == "true")
            {
                WriteStartElement("BaseType");
                Visit(value.BaseType);
                WriteEndElement();
            
                if (value.Events != null && value.Events.Count > 0)
                {
                    WriteStartElement("Events");
                    Visit(value.Events);
                    WriteEndElement();
                }

                if (value.Fields != null && value.Fields.Count > 0)
                {
                    WriteStartElement("Fields");
                    Visit(value.Fields);
                    WriteEndElement();
                }

                if (value.Methods != null && value.Methods.Count > 0)
                {
                    WriteStartElement("Methods");
                    Visit(value.Methods);
                    WriteEndElement();
                }

                if (value.Properties != null && value.Properties.Count > 0)
                {
                    WriteStartElement("Properties");
                    Visit(value.Properties);
                    WriteEndElement();
                }
                if (value.Interfaces != null && value.Interfaces.Count > 0)
                {
                    WriteStartElement("Interfaces");
                    Visit(value.Interfaces);
                    WriteEndElement();
                }

                if (value.NestedTypes != null && value.NestedTypes.Count > 0)
                {
                    WriteStartElement("NestedTypes");
                    Visit(value.NestedTypes);
                    WriteEndElement();
                }
            }

            WriteEndElement();
        }

        public void Visit(ITypeDeclarationCollection value)
        {
            if (value == null || value.Count == 0)
                return;

            WriteStartElement("ITypeDeclarationCollection");
            
            foreach (ITypeDeclaration typ in value)
            {
                Visit(typ);
            }

            WriteEndElement();
        }

        public void Visit(ITypeReference value)
        {
            if (value == null)
                return;

            WriteStartElement("ITypeReference");
            
            Manager.ReflectorVisitor.Visit((IGenericArgumentProvider)value);
            WriteElement("Name", value.Name);
            WriteElement("Namespace", value.Namespace);
            WriteElement("ValueType", value.ValueType.ToString());

            if (value.GenericType != null)
            {
                WriteStartElement("GenericType");
                Visit(value.GenericType);
                WriteEndElement();
            }

            WriteEndElement();
        }

        public void Visit(ITypeReferenceCollection value)
        {
            if (value == null || value.Count == 0)
                return;

            WriteStartElement("ITypeReferenceCollection");

            foreach (ITypeReference typ in value)
            {
                Visit(typ);
            }

            WriteEndElement();
        }

        public void Visit(IUnmanagedResource value)
        {
            if (value == null)
                return;

            WriteStartElement("IUnmanagedResource");

            WriteElement("CodePage", value.CodePage.ToString());
            WriteElement("Language", value.Language.ToString());
            WriteElement("Name", value.Name.ToString());
            WriteElement("Type", value.Type.ToString());
            WriteElement("ByteCount", value.Value.Length.ToString());

            WriteEndElement();
        }

        public void Visit(IUnmanagedResourceCollection value)
        {
            if (value == null || value.Count == 0)
                return;

            WriteStartElement("IUnmanagedResourceCollection");

            foreach (IUnmanagedResource res in value)
            {
                Visit(res);
            }

            WriteEndElement();
        }

        public void Visit(IValueTypeConstraint value)
        {
            if (value == null)
                return;
            
            WriteEmptyElement("IValueTypeConstraint");
        }
        
    }
}
